import { defineStore } from 'pinia';
import { DefineComponent } from 'vue';
import auth from '@/plugins/auth';
import router, { constantRoutes, dynamicRoutes } from '@/router';
import { getRouters } from '@/api/menu';
import Layout from '@/layout/index.vue';
import ParentView from '@/components/ParentView/index.vue';
import InnerLink from '@/layout/components/InnerLink/index.vue';
import { CustomRoute } from 'src/types/route'

// 匹配views里面所有的.vue文件
const modules = import.meta.glob('@/views/**/*.vue')

/**
 * 权限管理 store
 */
const usePermissionStore = defineStore(
  'permission',
  {
    state: () => ({
      routes: [] as CustomRoute[],
      addRoutes: [] as CustomRoute[],
      defaultRoutes: [] as CustomRoute[],
      topbarRouters: [] as CustomRoute[],
      sidebarRouters: [] as CustomRoute[]
    }),
    actions: {
      /**
       * 设置路由
       * @param routes - 路由数组
       */
      setRoutes(routes: any[]) {
        this.addRoutes = routes;
        this.routes = constantRoutes.concat(routes);
      },

      /**
       * 设置默认路由
       * @param routes - 默认路由数组
       */
      setDefaultRoutes(routes: any[]) {
        this.defaultRoutes = constantRoutes.concat(routes);
      },

      /**
       * 设置顶部栏路由
       * @param routes - 顶部栏路由数组
       */
      setTopbarRoutes(routes: any[]) {
        this.topbarRouters = routes;
      },

      /**
       * 设置侧边栏路由
       * @param routes - 侧边栏路由数组
       */
      setSidebarRouters(routes: any[]) {
        this.sidebarRouters = routes;
      },

      /**
       * @description 生成动态路由
       * @author 颜磊
       * @date 23/10/2024
       * @param {string[]} roles 用户角色
       * @return {*}  {Promise<any[]>}
       */
      generateRoutes(roles: string[]): Promise<any[]> {
        return new Promise(resolve => {
          // 向后端请求路由数据
          getRouters().then(res => {
            const sdata = JSON.parse(JSON.stringify(res.data)) as CustomRoute[];
            const rdata = JSON.parse(JSON.stringify(res.data))as CustomRoute[];;
            const defaultData = JSON.parse(JSON.stringify(res.data))as CustomRoute[];;

            const sidebarRoutes = filterAsyncRouter(sdata,undefined);
            const rewriteRoutes = filterAsyncRouter(rdata, undefined, true);
            const defaultRoutes = filterAsyncRouter(defaultData,undefined);
            const asyncRoutes = filterDynamicRoutes(dynamicRoutes);

            asyncRoutes.forEach(route => {
              router.addRoute(route);
            });

            this.setRoutes(rewriteRoutes);
            this.setSidebarRouters(constantRoutes.concat(sidebarRoutes));
            this.setDefaultRoutes(sidebarRoutes);
            this.setTopbarRoutes(defaultRoutes);

            resolve(rewriteRoutes);
          });
        });
      }
    }
  }
);


/**
 * @description 遍历后台传来的路由字符串，转换为组件对象
 * @author 颜磊
 * @date 23/10/2024
 * @param {Route[]} asyncRouterMap 动态路由映射
 * @param {Route} [lastRouter] 上一个路由
 * @param {boolean} [type=false] 类型标志
 * @return {*}  {any[]}
 */
function filterAsyncRouter(asyncRouterMap: CustomRoute[], lastRouter?: CustomRoute, type: boolean = false): any[] {
  return asyncRouterMap.filter(route => {
    if (type && route.children) {
      route.children = filterChildren(route.children,lastRouter);
    }
    if (route.component) {
      // Layout, ParentView, InnerLink 组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout;
      } else if (route.component === 'ParentView') {
        route.component = ParentView;
      } else if (route.component === 'InnerLink') {
        route.component = InnerLink;
      } else {
        route.component = loadView(route.component);
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type);
    } else {
      delete route['children'];
      delete route['redirect'];
    }
    return true;
  });
}

/**
 * 过滤子路由
 * @param childrenMap - 子路由映射
 * @param lastRouter - 上一个路由
 * @returns any[]
 */
function filterChildren(childrenMap: CustomRoute[], lastRouter?:CustomRoute): any[] {
  const children: any[] = [];
  childrenMap.forEach((el, index) => {
    if (el.children && el.children.length) {
      if (el.component === 'ParentView' && !lastRouter) {
        el.children.forEach(c => {
          c.path = el.path + '/' + c.path;
          if (c.children && c.children.length) {
            children.push(...filterChildren(c.children, c));
            return;
          }
          children.push(c);
        });
        return;
      }
    }
    if (lastRouter) {
      el.path = lastRouter.path + '/' + el.path;
    }
    children.push(el);
  });
  return children;
}

/**
 * 动态路由遍历，验证是否具备权限
 * @param routes - 路由数组
 * @returns any[]
 */
export function filterDynamicRoutes(routes: any[]): any[] {
  const res: any[] = [];
  routes.forEach(route => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route);
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route);
      }
    }
  });
  return res;
}

/**
 * 加载视图组件
 * @param view - 视图名称
 * @returns Function | undefined
 */
export const loadView = (view: string): (() => Promise<DefineComponent<{}, {}, any>>) | undefined => {
  let res: (() => Promise<DefineComponent<{}, {}, any>>) | undefined;
  for (const path in modules) {
    const dir = path.split('views/')[1].split('.vue')[0];
    if (dir === view) {
      res = () => modules[path]() as Promise<DefineComponent<{}, {}, any>>;;
    }
  }
  return res;
};

export {usePermissionStore};